home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Applications / QuArK / quarkpy / mapbtns.py < prev    next >
Text File  |  2004-01-05  |  25KB  |  748 lines

  1.  
  2. """   QuArK  -  Quake Army Knife
  3.  
  4. Map Editor Buttons and implementation of editing commands
  5. """
  6. #
  7. # Copyright (C) 1996-99 Armin Rigo
  8. # THIS FILE IS PROTECTED BY THE GNU GENERAL PUBLIC LICENCE
  9. # FOUND IN FILE "COPYING.TXT"
  10. #
  11.  
  12. #$Header: /cvsroot/quark/runtime/quarkpy/mapbtns.py,v 1.16 2003/12/18 21:51:46 peter-b Exp $
  13.  
  14.  
  15.  
  16. import quarkx
  17. import qtoolbar
  18. from qdictionnary import Strings
  19. from maputils import *
  20. from b2utils import *
  21.  
  22.  
  23.  
  24. #
  25. # Drag-and-drop functions
  26. #
  27.  
  28. def droptarget(editor, newitem):
  29.     "Where is the new item to be inserted ? (parent, insertbefore)"
  30.     ex = editor.layout.explorer
  31.     fs = ex.focussel     # currently selected item
  32.     if not fs is None:
  33.         if (fs.type==':p') and (newitem.type==':f'):
  34.             return fs, None   # put a face inside a polyhedron by default
  35.         if (fs.flags & OF_TVEXPANDED) and fs.acceptitem(newitem):
  36.             # never put an object into a closed group
  37.             if (fs.type!=":b") or (newitem.type==":p"):   # by default, only polyhedrons are put inside brush entities - other objects are put besides
  38.                 return fs, None    # put inside the selected object
  39.         while fs is not editor.Root:
  40.             oldfs = fs
  41.             fs = fs.parent
  42.             if fs.acceptitem(newitem):
  43.                 return fs, oldfs.nextingroup()   # can insert here, right after the previously selected item
  44.     if editor.Root.acceptitem(newitem):
  45.         return editor.Root, None   # in "worldspawn", at the end
  46.     # cannot insert new item at all...
  47.     return None, None
  48.  
  49.  
  50. def dropitemsnow(editor, newlist, text=Strings[544], center="S"):
  51.     "Drop new items into the given map editor."
  52.     #
  53.     # Known values of "center" :
  54.     #   <vector>: scroll at the given point
  55.     #   "S":      scroll at screen center or at the selected object's center
  56.     #   "0":      don't scroll at all
  57.     #   "+":      scroll at screen center or don't scroll at all
  58.     #
  59.     if len(newlist)==0:
  60.         return
  61.  
  62.     for newitem in newlist:
  63.         if "PixelSet" in newitem.classes:
  64.             applytexture(editor, newitem.shortname)
  65.             return 1
  66.     delta = None
  67.     if center != "0":
  68.         recenter = MapOption("Recenter")
  69.         if center != "+" or recenter:
  70.             bbox = quarkx.boundingboxof(newlist)
  71.             if bbox is None: #DECKER
  72.                 bbox = (quarkx.vect(-1,-1,-1),quarkx.vect(1,1,1)) #DECKER create a minimum bbox, in case a ;incl="defpoly" is added to an object in prepareobjecttodrop()
  73.             if not (bbox is None):
  74.                 if type(center)==type(""):
  75.                     if recenter:
  76.                         bbox1 = None
  77.                     else:
  78.                         bbox1 = quarkx.boundingboxof(editor.visualselection())
  79.                     if bbox1 is None:
  80.                         center = editor.layout.screencenter()
  81.                     else:
  82.                         center = (bbox1[0]+bbox1[1])*0.5
  83.                 delta = center - (bbox[0]+bbox[1])*0.5
  84.                 delta = editor.aligntogrid(delta)
  85.     undo = quarkx.action()
  86.     for newitem in newlist:
  87.         nparent, nib = droptarget(editor, newitem)
  88.         if nparent is None:
  89.             undo.cancel()    # not required, but it's better when it's done
  90.             msg = Strings[-101]
  91.             #if "Image" in newitem.classes:
  92.             #    msg = msg + Strings[-102]
  93.             quarkx.msgbox(msg, MT_ERROR, MB_OK)
  94.             return
  95.         new = newitem.copy()
  96.         prepareobjecttodrop(editor, new)
  97.         if delta:
  98.             new.translate(delta)
  99.         undo.put(nparent, new, nib)
  100.     undo.ok(editor.Root, text)
  101.     editor.layout.actionmpp()
  102.     return 1
  103.  
  104. def dropitemnow(editor, newitem):
  105.     "Drop a new item into the given map editor."
  106.     dropitemsnow(editor, [newitem], Strings[616])
  107.  
  108.  
  109. def applytexture(editor, texname):
  110.     undo = quarkx.action()
  111.     for s in editor.layout.explorer.sellist:
  112.         new = s.copy()
  113.         new.replacetex('', texname)
  114.         undo.exchange(s, new)
  115.     undo.ok(editor.Root, Strings[546])
  116.  
  117.  
  118.  
  119. def replacespecifics(obj, mapping):
  120.     "Set the 'target' and 'targetname' Specifics."
  121.     if obj["target"]=="[auto]":
  122.         obj["target"] = mapping["target"]
  123.     if obj["targetname"]=="[auto]":
  124.         obj["targetname"] = mapping["targetname"]
  125.     for o in obj.subitems:
  126.         replacespecifics(o, mapping)
  127.  
  128. def textureof(editor):
  129.     texlist = quarkx.texturesof(editor.layout.explorer.sellist)
  130.     if len(texlist)==1:
  131.         return texlist[0]
  132.     else:
  133.         return quarkx.setupsubset()["DefaultTexture"]
  134.  
  135. def prepareobjecttodrop(editor, obj):
  136.     "Call this to prepare an object to be dropped. It replaces [auto] Specifics."
  137.  
  138.     oldincl = obj[";incl"]
  139.     obj[";desc"] = None
  140.     obj[";incl"] = None
  141.     if not ("TreeMap" in obj.classes):
  142.         return
  143.  
  144.     # replace the textures "[auto]", "[trigger]", "[clip]", "[origin]" and "[caulk]"
  145.     tex = textureof(editor)
  146.     obj.replacetex("[auto]", tex)
  147.     try:
  148.         tex_for_trigger = quarkx.setupsubset()["DefaultTextureTrigger"]
  149.         obj.replacetex("[trigger]", tex_for_trigger)
  150.     except:
  151.         tex_for_trigger = "[trigger]"
  152.  
  153.     try:
  154.         tex_for_clip = quarkx.setupsubset()["DefaultTextureClip"]
  155.         obj.replacetex("[clip]", tex_for_clip)
  156.     except:
  157.         tex_for_clip = "[clip]"
  158.  
  159.     try:
  160.         tex_for_origin = quarkx.setupsubset()["DefaultTextureOrigin"]
  161.         obj.replacetex("[origin]", tex_for_origin)
  162.     except:
  163.         tex_for_origin = "[origin]"
  164.  
  165.     try:
  166.         tex_for_caulk = quarkx.setupsubset()["DefaultTextureCaulk"]
  167.         obj.replacetex("[caulk]", tex_for_caulk)
  168.     except:
  169.         tex_for_caulk = "[caulk]"
  170.  
  171.     # try to replace whatever ";incl" tells us to do
  172.     if (oldincl is not None) and (oldincl <> ""):
  173.         try:
  174.             # Get the user's default poly XYZ-size
  175.             defpoly = quarkx.setupsubset(SS_MAP, "Building")["DefPoly"]
  176.             defpolysize = defpoly.split("x")
  177.         except:
  178.             defpolysize = ["64", "64", "64"]
  179.         try:
  180.             # Convert the text-values to int-values
  181.             defpolysize[0] = int(defpolysize[0])
  182.             defpolysize[1] = int(defpolysize[1])
  183.             defpolysize[2] = int(defpolysize[2])
  184.             # minimum values are "8x8x8"
  185.             if (defpolysize[0] < 8) or (defpolysize[1] < 8) or (defpolysize[2] < 8):
  186.                 # Silent exception, since the next 'except' will catch it.
  187.                 raise "Problem with 'Default polyhedron size'"
  188.         except:
  189.             defpolysize = [64, 64, 64] # must be an array of three values
  190.         oldincl = oldincl.lower()
  191.         if (oldincl.find("poly") > -1):
  192.             # Create a default-poly
  193.             obj.appenditem(newcubeXYZ(defpolysize[0], defpolysize[1], defpolysize[2], tex))
  194.         if (oldincl.find("trigger") > -1):
  195.             # Create a trigger-poly
  196.             obj.appenditem(newcubeXYZ(defpolysize[0], defpolysize[1], defpolysize[2], tex_for_trigger, "trigger poly"))
  197.         if (oldincl.find("clip") > -1):
  198.             # Create a clip-poly
  199.             obj.appenditem(newcubeXYZ(defpolysize[0], defpolysize[1], defpolysize[2], tex_for_clip, "clip poly"))
  200.         if (oldincl.find("origin") > -1):
  201.             # Create a origin-poly half the X/Y-size, and 1.5 less the Z-size
  202.             obj.appenditem(newcubeXYZ(defpolysize[0]/2, defpolysize[1]/2, defpolysize[2]/1.5, tex_for_origin, "origin poly"))
  203.         if (oldincl.find("caulk") > -1):
  204.             # Create a caulk-poly
  205.             obj.appenditem(newcubeXYZ(defpolysize[0], defpolysize[1], defpolysize[2], tex_for_caulk, "caulk poly"))
  206.  
  207.     # replace "target" and "targetname"
  208.     try:
  209.         replacespecifics(obj, {})
  210.     except KeyError:   # "target" or "targetname" really found in obj
  211.         list = editor.AllEntities()
  212.         lt, ltn = 0,0
  213.         for e in list:
  214.             s = e["target"]
  215.             if (s is not None) and (s[:1]=="t"):
  216.                 try:
  217.                     lt = max((lt, int(s[1:])))
  218.                 except:
  219.                     pass
  220.             s = e["targetname"]
  221.             if (s is not None) and (s[:1]=="t"):
  222.                 try:
  223.                     ltn = max((ltn, int(s[1:])))
  224.                 except:
  225.                     pass
  226.         if lt==0 or ltn>=lt: lt=lt+1
  227.         if ltn==0 or lt>=ltn: ltn=ltn+1
  228.         replacespecifics(obj, {"target": "t%d"%lt, "targetname": "t%d"%ltn})
  229.  
  230.  
  231. def mapbuttonclick(self):
  232.     "Drop a new map object from a button."
  233.     editor = mapeditor()
  234.     if editor is None: return
  235.     def processObject(object):
  236.         object=object.copy()
  237.         scale = quarkx.setupsubset()["DefaultTextureScale"]
  238.         if scale and not object["fixedscale"]:
  239.             scale = eval(scale)
  240.             for face in object.findallsubitems("",":f"):
  241.                 texp = face.threepoints(2)
  242.                 p0 = texp[0]
  243.                 v1, v2 = (texp[1]-p0)*scale, (texp[2]-p0)*scale
  244.                 face.setthreepoints((p0,p0+v1,p0+v2),2)
  245.         object["fixedscale"]=None
  246.         return object
  247.     dropitemsnow(editor, map(processObject, self.dragobject))
  248.  
  249.  
  250.  
  251. #
  252. # General editing commands.
  253. #
  254.  
  255. def deleteitems(root, list, actiontext=None):
  256.     undo = quarkx.action()
  257.     text = None
  258.     for s in list:
  259.         if (s is not root) and checktree(root, s):    # only delete items that are childs of 'root'
  260.             if text is None:
  261.                 text = Strings[582] % s.shortname
  262.             else:
  263.                 text = Strings[579]   # multiple items selected
  264.             undo.exchange(s, None)   # replace all selected objects with None
  265.     if text is None:
  266.         undo.cancel()
  267.         quarkx.beep()
  268.     else:
  269.         undo.ok(root, actiontext or text)
  270.  
  271.  
  272. def edit_del(editor, m=None):
  273.     deleteitems(editor.Root, editor.visualselection())
  274.  
  275. def edit_copy(editor, m=None):
  276.     quarkx.copyobj(editor.visualselection())
  277.  
  278. def edit_cut(editor, m=None):
  279.     edit_copy(editor, m)
  280.     deleteitems(editor.Root, editor.visualselection(), Strings[542])
  281.  
  282. def edit_paste(editor, m=None):
  283.     newitems = quarkx.pasteobj(1)
  284.     try:
  285.         origin = m.origin
  286.     except:
  287.         origin = "+"
  288.     if not dropitemsnow(editor, newitems, Strings[543], origin):
  289.         quarkx.beep()
  290.  
  291. def edit_dup(editor, m=None):
  292.     if not dropitemsnow(editor, editor.visualselection(), Strings[541], "0"):
  293.         quarkx.beep()
  294.  
  295.  
  296. def edit_newgroup(editor, m=None):
  297.     "Create a new group."
  298.  
  299.     #
  300.     # List selected objects.
  301.     #
  302.  
  303.     list = editor.visualselection()
  304.  
  305.     #
  306.     # Build a new group object.
  307.     #
  308.  
  309.     newgroup = quarkx.newobj("group:g")
  310.  
  311.     #
  312.     # Determine where to drop this new group.
  313.     #
  314.  
  315.     ex = editor.layout.explorer
  316.     nparent = ex.focussel     # currently selected item
  317.     if not nparent is None:
  318.         nib = nparent
  319.         nparent = nparent.parent
  320.     if nparent is None:
  321.         nparent = editor.Root
  322.         nib = None
  323.  
  324.     #
  325.     # Do it !
  326.     #
  327.  
  328.     undo = quarkx.action()
  329.     undo.put(nparent, newgroup, nib)   # actually create the new group
  330.     for s in list:
  331.         if s is not editor.Root and s is not nparent:
  332.             undo.move(s, newgroup)   # put the selected items into the new group
  333.     undo.ok(editor.Root, Strings[556])
  334.  
  335.     #
  336.     # Initially expand the new group.
  337.     #
  338.  
  339.     editor.layout.explorer.expand(newgroup)
  340.  
  341.  
  342.  
  343. def texturebrowser(reserved=None):
  344.     "Opens the texture browser."
  345.  
  346.     #
  347.     # Get the texture to select from the current selection.
  348.     #
  349.  
  350.     editor = mapeditor()
  351.     if editor is None:
  352.         seltex = None
  353.     else:
  354.         texlist = quarkx.texturesof(editor.layout.explorer.sellist)
  355.         if len(texlist)==1:
  356.             seltex = quarkx.loadtexture(texlist[0], editor.TexSource)
  357.         else:
  358.             seltex = None
  359.  
  360.     #
  361.     # Open the Texture Browser tool box.
  362.     #
  363.  
  364.     quarkx.opentoolbox("", seltex)
  365.  
  366.  
  367.  
  368. #def warninginvfaces(editor):
  369. #   "Delete invalid faces with user confirmation."
  370. #
  371. #   for typ1, msg1 in ((':p', 159), (':f', 157)):
  372. #       list = editor.Root.findallsubitems("", typ1)
  373. #       list = filter(lambda f: f.broken, list)
  374. #       if len(list):
  375. #           if len(list)==1:
  376. #               msg = Strings[msg1+1]
  377. #           else:
  378. #               msg = Strings[msg1]%len(list)
  379. #           if quarkx.msgbox(msg, MT_CONFIRMATION, MB_YES | MB_NO) == MR_YES:
  380. #               SetMapOption("DeleteFaces", 1)
  381. #               undo = quarkx.action()
  382. #               for f in list:
  383. #                   undo.exchange(f, None)   # replace all broken faces with None
  384. #               undo.ok(editor.Root, Strings[602]%len(list))
  385. #               break
  386.  
  387.  
  388. def resettexscale(editor, flist, adjust):
  389.     #
  390.     # adjust=0: reset 1:1 texture scale
  391.     # adjust=1: adjust the texture on the face
  392.     # adjust=2: adjust the texture on the face but keep scaling to a minimum
  393.     #
  394.     undo = quarkx.action()
  395.     for f in flist:
  396.  
  397.         #
  398.         # Read the three points that determine the texture on the face.
  399.         #
  400.  
  401.         tp = f.threepoints(1)
  402.         if tp is None: continue
  403.         tp0 = tp[0]
  404.  
  405.         if adjust:
  406.             #
  407.             # Adjust the texture on the face.
  408.             #
  409.  
  410.             #
  411.             # Get the direction of the two vectors on the texture.
  412.             #
  413.             tp1, tp2 = (tp[1]-tp0).normalized, (tp[2]-tp0).normalized
  414.             #
  415.             # Enumerate all vertices of the face.
  416.             #
  417.             s,t = [], []
  418.             for vlist in f.vertices:
  419.                 for v in vlist:
  420.                     v = v-tp0
  421.                     #
  422.                     # Compute the projections of the vertices on the tp1 and tp2 axis
  423.                     #
  424.                     s.append(v*tp1)
  425.                     t.append(v*tp2)
  426.  
  427.             #
  428.             # We move the three texture points using the minimum and maximum values
  429.             # computed in the s and t lists.
  430.             #
  431.  
  432.             if adjust == 1:
  433.                 tp = (
  434.                    (tp0 + min(s)*tp1 + min(t)*tp2,
  435.                     tp0 + max(s)*tp1 + min(t)*tp2,
  436.                     tp0 + min(s)*tp1 + max(t)*tp2),
  437.                  2, editor.TexSource)
  438.             else:
  439.                     tex = f .texturename
  440.                     texobj = quarkx .loadtexture (tex, editor.TexSource)
  441.                     if texobj is not None:
  442.                         try:
  443.                             texobj = texobj .disktexture
  444.                         except quarkx.error:
  445.                             texobj = None
  446.                     size = (128.0,128.0)
  447.                     #print size
  448.                     if texobj is not None:
  449.                         size = texobj ["size"]
  450.  
  451.                     tpn0 = tp0 + min(s)*tp1 + min(t)*tp2
  452.                     tpn1 = tp0 + max(s)*tp1 + min(t)*tp2
  453.                     tpn2 = tp0 + min(s)*tp1 + max(t)*tp2
  454.                     l = abs (tpn1 - tpn0)
  455.                     s1 = round (l / size [0])
  456.                     if s1 == 0:
  457.                         s1 = 1
  458.                     s1 = l / s1
  459.                     l = abs (tpn2 - tpn0)
  460.                     s2 = round (l / size [1])
  461.                     if s2 == 0:
  462.                         s2 = 1
  463.                     s2 = l / s2
  464.                     tp = (
  465.                        (tpn0,
  466.                         tpn0 + s1 * (tpn1 - tpn0) .normalized,
  467.                         tpn0 + s2 * (tpn2 - tpn0) .normalized),
  468.                        2, editor.TexSource)
  469.  
  470.         else:
  471.             #
  472.             # Reset 1:1 texture scale.
  473.             #
  474.             # First compute two "good" vectors to use as new directions on the texture.
  475.             #
  476.  
  477.             n = f.normal
  478.             if not n: continue
  479.             #
  480.             # The first is computed with orthogonalvect.
  481.             #
  482.             v = orthogonalvect(n, editor.layout.views[0])
  483.             #
  484.             # The second should be orthogonal to the first one
  485.             #
  486.             w = n^v
  487.             #
  488.             # We keep the same origin, but let's force it to grid.
  489.             #
  490.             tp0g = editor.aligntogrid(tp0)
  491.             tp0 = tp0g + n*((tp0-tp0g)*n)   # should stay in the same plane
  492.             #
  493.             # Now we can compute the three new texture points.
  494.             #
  495.             tp = ((tp0, tp0 + 128*v, tp0 + 128*w), 3)
  496.  
  497.         #
  498.         # We can make a copy of the face and apply the new texture points in it.
  499.         #
  500.  
  501.         new = f.copy()
  502.         apply(new.setthreepoints, tp)
  503.         undo.exchange(f, new)  # replace f with new
  504.  
  505.     #
  506.     # Commit changes.
  507.     #
  508.  
  509.     editor.ok(undo, Strings[619+(not adjust)])
  510.  
  511.  
  512. def moveselection(editor, text, offset=None, matrix=None, origin=None, inflate=None):
  513.     "Move the selection and/or apply a linear mapping on it."
  514.  
  515.     #
  516.     # Get the list of selected items.
  517.     #
  518.     items = editor.visualselection()
  519.     if len(items):
  520.         if matrix and (origin is None):
  521.             #
  522.             # Compute a suitable origin if none is given
  523.             #
  524.             origin = editor.interestingpoint()
  525.             if origin is None:
  526.                 if len(items)==1 and items[0]["usercenter"]:
  527.                     origin=quarkx.vect(items[0]["usercenter"])
  528.                 else:
  529.                     bbox = quarkx.boundingboxof(items)
  530.                     if bbox is None:
  531.                         origin = quarkx.vect(0,0,0)
  532.                     else:
  533.                         origin = (bbox[0]+bbox[1])*0.5
  534.  
  535.         direct = (len(items)==1) and (items[0].type == ':d')    # Duplicators
  536.         undo = quarkx.action()
  537.         #
  538.         # patches with picked control points
  539.         #
  540.         pickedObjects=[]
  541.         for obj in items:
  542.             if obj.type==":b2" and obj["picked"] is not None:
  543.                 pickedObjects.append(obj)
  544.                 continue
  545.             new = obj.copy()
  546.             if offset:
  547.                 new.translate(offset)     # offset the objects
  548.             if matrix:
  549.                 if direct:
  550.                     import mapduplicator
  551.                     mapduplicator.DupManager(new).applylinear(matrix, 1)
  552.                 else:
  553.                     new.linear(origin, matrix)   # apply the linear mapping
  554.                     for item in new.findallsubitems("",":g"):
  555.                         center = item["usercenter"]
  556.                         if center is not None:
  557.                             newcenter = matrix*(quarkx.vect(center)-origin)+origin
  558.                             item["usercenter"]=newcenter.tuple
  559.             if inflate:
  560.                 new.inflate(inflate)    # inflate / deflate
  561.             undo.exchange(obj, new)
  562.         if pickedObjects:
  563.             list = []
  564.             for obj in pickedObjects:
  565.                 cp = obj.cp
  566.                 for p in obj["picked"]:
  567.                     i, j = cpPos(p, obj)
  568.                     list.append(quarkx.vect(cp[i][j].xyz))
  569.             center = reduce(lambda x, y:x+y,list)/len(list)
  570.             for obj in pickedObjects:
  571.                 new = obj.copy()
  572.                 cp=copyCp(obj.cp)
  573.                 for p in obj["picked"]:
  574.                     i, j = cpPos(p, obj)
  575.                     st = cp[i][j].st
  576.                     pos = quarkx.vect(cp[i][j].xyz)
  577.                     if offset:
  578.                         cp[i][j]=quarkx.vect((pos+offset).tuple+st)
  579.                     if inflate:
  580.                         v = inflate*((pos-center).normalized)
  581.                         cp[i][j]=quarkx.vect((pos+v).tuple+st)
  582.                     if matrix:
  583.                         p2 = pos-center
  584.                         p3 = matrix*p2
  585.                         p4 = p3+center
  586.                         cp[i][j]=quarkx.vect(p4.tuple+st)
  587.                 new.cp = cp
  588.                 undo.exchange(obj, new)
  589.  
  590.         editor.ok(undo, text)
  591.  
  592.     else:
  593.         #
  594.         # No selection.
  595.         #
  596.         quarkx.msgbox(Strings[222], MT_ERROR, MB_OK)
  597.  
  598.  
  599.  
  600. def ForceToGrid(editor, grid, sellist):
  601.     undo = quarkx.action()
  602.     for obj in sellist:
  603.         new = obj.copy()
  604.         new.forcetogrid(grid)
  605.         undo.exchange(obj, new)
  606.     editor.ok(undo, Strings[560])
  607.  
  608.  
  609. def groupcolor(m):
  610.     editor = mapeditor()
  611.     if editor is None: return
  612.     group = editor.layout.explorer.uniquesel
  613.     if (group is None) or (group.type != ':g'):
  614.         return
  615.     oldval = group["_color"]
  616.     if m.rev:
  617.         nval = None
  618.     else:
  619.         try:
  620.             oldval = quakecolor(quarkx.vect(oldval))
  621.         except:
  622.             oldval = 0
  623.         nval = editor.form.choosecolor(oldval)
  624.         if nval is None: return
  625.         nval = str(colorquake(nval))
  626.     if nval != oldval:
  627.         undo = quarkx.action()
  628.         undo.setspec(group, "_color", nval)
  629.         undo.ok(editor.Root, Strings[622])
  630.  
  631.  
  632. def newcubeXYZ(dx, dy, dz, tex, cubename="poly"):
  633.     p = quarkx.newobj(cubename + ":p")
  634.     dx=dx*0.5
  635.     dy=dy*0.5
  636.     dz=dz*0.5
  637.  
  638.     f = quarkx.newobj("east:f");   f["v"] = (dx, -dy, -dz, dx, 128-dy, -dz, dx, -dy, 128-dz)
  639.     f["tex"] = tex
  640.     p.appenditem(f)
  641.  
  642.     f = quarkx.newobj("west:f");   f["v"] = (-dx, -dy, -dz, -dx, -dy, 128-dz, -dx, 128-dy, -dz)
  643.     f["tex"] = tex             ;   f["m"] = "1"
  644.     p.appenditem(f)
  645.  
  646.     f = quarkx.newobj("north:f");  f["v"] = (-dx, dy, -dz, -dx, dy, 128-dz, 128-dx, dy, -dz)
  647.     f["tex"] = tex              ;  f["m"] = "1"
  648.     p.appenditem(f)
  649.  
  650.     f = quarkx.newobj("south:f");  f["v"] = (-dx, -dy, -dz, 128-dx, -dy, -dz, -dx, -dy, 128-dz)
  651.     f["tex"] = tex
  652.     p.appenditem(f)
  653.  
  654.     f = quarkx.newobj("up:f");     f["v"] = (-dx, -dy, dz, 128-dx, -dy, dz, -dx, 128-dy, dz)
  655.     f["tex"] = tex
  656.     p.appenditem(f)
  657.  
  658.     f = quarkx.newobj("down:f");   f["v"] = (-dx, -dy, -dz, -dx, 128-dy, -dz, 128-dx, -dy, -dz)
  659.     f["tex"] = tex             ;   f["m"] = "1"
  660.     p.appenditem(f)
  661.  
  662.     return p
  663.  
  664. def newcube(size, tex):
  665.     return newcubeXYZ(size, size, size, tex)
  666.  
  667.  
  668. def groupview1click(m):
  669.     editor = mapeditor(SS_MAP)
  670.     if editor is None: return
  671.     grouplist = filter(lambda o: o.type==':g', editor.layout.explorer.sellist)
  672.     undo = quarkx.action()
  673.     for group in grouplist:
  674.         try:
  675.             viewstate = int(group[";view"])
  676.         except:
  677.             viewstate = 0
  678.         if m.flag &~ (VF_GRAYEDOUT|VF_HIDDEN):      # toggle items
  679.             if m.state == qmenu.checked:
  680.                 viewstate = viewstate &~ m.flag
  681.             else:
  682.                 viewstate = viewstate | m.flag
  683.         else:
  684.             viewstate = (viewstate &~ (VF_GRAYEDOUT|VF_HIDDEN)) | m.flag
  685.             if m.flag == 0:
  686.                 viewstate = viewstate &~ (VF_CANTSELECT|VF_HIDEON3DVIEW)
  687.             elif m.flag == VF_HIDDEN:
  688.                 viewstate = viewstate | (VF_CANTSELECT|VF_HIDEON3DVIEW)
  689.         if viewstate:
  690.             nval = `viewstate`
  691.         else:
  692.             nval = None
  693.         undo.setspec(group, ";view", nval)
  694.     undo.ok(editor.Root, Strings[590])
  695.  
  696. # ----------- REVISION HISTORY ------------
  697. #
  698. #
  699. #$Log: mapbtns.py,v $
  700. #Revision 1.16  2003/12/18 21:51:46  peter-b
  701. #Removed reliance on external string library from Python scripts (second try ;-)
  702. #
  703. #Revision 1.15  2003/12/17 13:58:59  peter-b
  704. #- Rewrote defines for setting Python version
  705. #- Removed back-compatibility with Python 1.5
  706. #- Removed reliance on external string library from Python scripts
  707. #
  708. #Revision 1.14  2002/05/18 22:31:56  tiglari
  709. #remove debug statement
  710. #
  711. #Revision 1.13  2001/08/23 22:11:01  tiglari
  712. #usercenters now move when higher groups are rotated etc.
  713. #
  714. #Revision 1.12  2001/04/17 23:29:07  tiglari
  715. #texture-rescaling bug fix (fixedscale="1" added to objects when they're
  716. #dragged to the panel, removed when inserted to the map, blocks
  717. #rescaling of textures on insert-by-pressing-panel-button
  718. #
  719. #Revision 1.11  2001/04/03 21:09:28  tiglari
  720. #cleaned out debug statements
  721. #
  722. #Revision 1.10  2001/03/31 13:00:16  tiglari
  723. #rotate around usercenter if there is one
  724. #
  725. #Revision 1.9  2001/02/20 08:05:21  tiglari
  726. #DefaultTextureScale implemented
  727. #
  728. #Revision 1.8  2001/01/27 18:24:53  decker_dk
  729. #Renamed 'TextureDef' -> 'DefaultTexture'
  730. #Renamed 'TriggerTextureDef' -> 'DefaultTextureTrigger'
  731. #Added functionality to replace '[trigger]', '[clip]', '[origin]' and '[caulk]' texturenames.
  732. #Changed the ';incl' function. Now it accepts values; "poly,trigger,clip,origin", and more than one can be specified to include, for instance a 'poly' and an 'origin' cube.
  733. #
  734. #Revision 1.7  2000/12/31 23:59:44  tiglari
  735. #fixed adjust texture to fit face button problem (introduced by botched tab elimination)
  736. #
  737. #Revision 1.6  2000/12/30 05:29:37  tiglari
  738. #moveselection acts on picked cp's of bezier patches if any are picked
  739. #
  740. #Revision 1.5  2000/12/29 08:10:42  tiglari
  741. #extirpated tabs, hopefully without introducing errors...
  742. #
  743. #Revision 1.4  2000/06/02 16:00:22  alexander
  744. #added cvs headers
  745. #
  746. #
  747. #
  748.